import InterceptorManager from "./InterceptorManager";
import uniRequest from "./uni-request";

function Axios() {
  this._config = {};

  function createInstance(that) {
    that.interceptors = {
      request: new InterceptorManager(),
      response: new InterceptorManager(),
    };
    return that;
  }

  const create = (options) => {
    this._config = { ...options };
    return createInstance(this);
  };
  return { create };
}

const handleRequest = (interceptors, config) => {
  return new Promise(async (resolve, reject) => {
    const requestHandles = interceptors.request.handles;

    let filledConfig = null;

    try {
      filledConfig = requestHandles.fulfilled({ ...config });
    } catch (error) {
      return requestHandles.rejected(error).catch((error) => reject(error));
    }

    const responseHandles = interceptors.response.handles;
    uniRequest(filledConfig)
      .then((res) => {
        res.config = config;
        try {
          resolve(responseHandles.fulfilled(res));
        } catch (error) {
          return responseHandles.rejected(error).catch((error) => reject(error));
        }
      })
      .catch((err) => {
        if (err.errMsg) {
          return responseHandles.rejected({ message: err.errMsg }).catch((error) => reject(error));
        } else {
          return responseHandles.rejected(err).catch((error) => reject(error));
        }
      });
  });
};

Axios.prototype.get = function _get(url, options) {
  this._config.headers = {};
  this._config = { ...this._config, url, ...options };
  this._config.method = "GET";

  return handleRequest(this.interceptors, this._config);
};

Axios.prototype.post = function _post(url, data, options) {
  this._config.headers = {};
  this._config = { ...this._config, url, data, ...options };
  this._config.method = "POST";

  return handleRequest(this.interceptors, this._config);
};

export default new Axios();
